package pls_parser;

import java.io.File;
import java.io.InputStreamReader;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Map;
import java.util.TreeMap;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import utils.Logger;
import utils.config.Config;

public class PLSParser {
	
	static Config conf = null;
	private static final int BUFFER_SIZE = 1048576;
	
	
	private static Calendar startTime = null;
	private static Calendar endTime = null;
	
	public static void parse(BufferAnalyzer ba) throws Exception {
		
		conf = Config.getInstance();
		startTime = conf.pls_start_time;
		endTime = conf.pls_end_time;
		
		if(ba instanceof UsersAroundAnEvent) {
			startTime = ((UsersAroundAnEvent)ba).startTime;
			endTime = ((UsersAroundAnEvent)ba).endTime;
		}
		
		
		
		String dir = conf.pls_folder;
		long startTime = System.currentTimeMillis();
		
		analyzeDirectory(new File(dir),ba);
		
		long endTime = System.currentTimeMillis();
		int mins = (int)((endTime - startTime) / 60000);
		Logger.logln("Completed after "+mins+" mins");
	}
	
	
	static final String[] MONTHS = new String[]{"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
	private static void analyzeDirectory(File directory, BufferAnalyzer analyzer) throws Exception{
		Map<String,String> allDays = new TreeMap<String,String>();
		File[] items = directory.listFiles();
		for(int i=0; i<items.length;i++){
			File item = items[i];
			if(item.isFile()) {
				Calendar cal = new GregorianCalendar();
				String n = item.getName();
				cal.setTimeInMillis(Long.parseLong(n.substring(n.lastIndexOf("_")+1, n.indexOf(".zip"))));
				
				if(cal.before(startTime) || cal.after(endTime)) continue;
				
				String key = cal.get(Calendar.DAY_OF_MONTH)+"/"+MONTHS[cal.get(Calendar.MONTH)]+"/"+cal.get(Calendar.YEAR);
				String h = allDays.get(key);
				allDays.put(key, h==null? cal.get(Calendar.HOUR_OF_DAY)+"-" : h+cal.get(Calendar.HOUR_OF_DAY)+"-");
				
				analyzeFile(item, analyzer);
				if((i+1) % 10 == 0) Logger.logln(i+"/"+items.length+" done!");
			}
			else if(item.isDirectory())
				analyzeDirectory(item, analyzer);
		}
		
		Logger.logln("Days in the dataset:");
		for(String d:allDays.keySet()) 
			Logger.logln(d+" = "+allDays.get(d));
		
		
	}
	
	
	private static void analyzeFile(File plsFile, BufferAnalyzer analyzer) throws Exception {		
		ZipFile zf = new ZipFile(plsFile);
		ZipEntry ze = (ZipEntry) zf.entries().nextElement();
			
		InputStreamReader isr = new InputStreamReader(zf.getInputStream(ze));
		int charRead = 0;
		char[] read_buffer = new char[BUFFER_SIZE];
		char[] buffer = new char[3*BUFFER_SIZE];
		int x = -1;
		int remainedChars = 0;
		while(((charRead = isr.read(read_buffer)) > 0)){
			if(x==-1){
					x = analyzer.process(read_buffer, charRead);
					remainedChars = (charRead-x);
					System.arraycopy(read_buffer, x, buffer, 0, remainedChars);
			}
			else{
				System.arraycopy(read_buffer, 0, buffer, remainedChars, charRead);
				x = analyzer.process(buffer, (charRead+remainedChars));
				remainedChars = (charRead+remainedChars-x);
				System.arraycopy(buffer, x, buffer, 0, remainedChars);
			}
						
		}
		isr.close();
		zf.close();
	}
}
